﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO.Packaging;
using System.Data;
using Quexcel.OpenXML.Exceptions;
using System.IO;

namespace Quexcel.OpenXML
{
    public class ExcelTransaction : IDisposable
    {
        internal ExcelConnection connection;
        private Dictionary<PackagePart, XmlDocument> openWorksheets;

        public ExcelTransaction(ExcelConnection connection)
        {
            if (connection == null || connection.State == ConnectionState.Broken)
                throw new InvalidConnectionStateException(connection.State, "Invalid connection passed to transaction.");
            this.connection = connection;
            this.openWorksheets = new Dictionary<PackagePart,XmlDocument>();
        }

        public void Commit()
        {
            Dictionary<PackagePart, XmlDocument> tempOpenWorksheets = new Dictionary<PackagePart, XmlDocument>();
            try
            {
                foreach (PackagePart sheetPart in openWorksheets.Keys)
                {
                    tempOpenWorksheets.Add(sheetPart, openWorksheets[sheetPart]);
                }

                foreach (PackagePart sheetPart in openWorksheets.Keys)
                {
                    openWorksheets[sheetPart].Save(sheetPart.GetStream(FileMode.Create, FileAccess.Write));
                }
            }
            catch
            {
                foreach (PackagePart sheetPart in tempOpenWorksheets.Keys)
                {
                    openWorksheets[sheetPart] = tempOpenWorksheets[sheetPart];
                    tempOpenWorksheets[sheetPart].Save(sheetPart.GetStream(FileMode.Create, FileAccess.Write));
                }
            }
            finally
            {
                tempOpenWorksheets = null;
            }
        }

        public void Rollback()
        {
            try
            {
                foreach (PackagePart sheetPart in openWorksheets.Keys)
                {
                    // reset the xml document content
                    openWorksheets[sheetPart].Load(sheetPart.GetStream());
                }
            }finally
            {
                
            }
        }

        internal XmlDocument Open(PackagePart sheetPart)
        {
            XmlDocument worksheetDoc = null;
            if (openWorksheets.ContainsKey(sheetPart))
                worksheetDoc = openWorksheets[sheetPart];
            else
            {
                worksheetDoc = new XmlDocument();
                worksheetDoc.Load(sheetPart.GetStream());
                openWorksheets.Add(sheetPart, worksheetDoc);
            }

            return worksheetDoc;
        }
    
        #region IDisposable Members

        public void  Dispose()
        {
            try
            {
                this.Commit();
            }
            finally
            {
                openWorksheets = null;
            }
        }

        #endregion
    }
}
